package drds.configuration.mvc.core;

import drds.configuration.common.Constants;
import drds.configuration.mvc.aop.ActionExecutor;
import drds.configuration.mvc.config.MvcConstants;
import drds.configuration.mvc.config.UserConfig;
import drds.configuration.mvc.render.ActionRender;
import drds.configuration.mvc.render.Render;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public final class PrepareAndExecuteFilter implements Filter {

    private static final String Index_Url = "/";
    private static final String Index_Url_To_Action_Url = "/index/index.html";
    private static Logger logger = LoggerFactory.getLogger(PrepareAndExecuteFilter.class);
    /**
     * 用户配置信息
     */
    private UserConfig userConfig = null;

    public void destroy() {
    }

    // 加载配置文件
    public void init(FilterConfig filterConfig) throws ServletException {
        // 接受配置参数
        String webContentUserConfigClass = filterConfig.getInitParameter("webContentUserConfigClass");
        String actionExtension = filterConfig.getInitParameter("actionExtension");
        String devMode = filterConfig.getInitParameter("devMode");
        ServletContext servletContext = filterConfig.getServletContext();
        WebContent.staticMap.put(WebContent.SERVLET_CONTEXT, servletContext);
        //
        if (actionExtension != null && !"".equals(actionExtension.trim())) {
            MvcConstants.actionExtension = actionExtension;
            MvcConstants.isUseActionExtension = true;
        }
        if (devMode != null && ("true".equalsIgnoreCase(devMode) || "false"
                .equalsIgnoreCase(devMode))) {
            Constants.devMode = Boolean.parseBoolean(devMode);

        }

        if (webContentUserConfigClass == null) {
            throw new IllegalArgumentException("/web.xml/webContentUserConfigClass");
        }
        try {
            userConfig = (UserConfig) Class.forName(webContentUserConfigClass).newInstance();
            if (userConfig == null) {
                throw new IllegalArgumentException(
                        "/web.xml/webContentUserConfigClass[" + webContentUserConfigClass
                                + "] can not init ok");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        boolean initok = false;
        try {
            initok = WebContent.initWebContent(userConfig);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }
        if (!initok) {
            throw new IllegalArgumentException("框架初始化失败");
        }

    }

    /**
     * 接管动态请求，控制 action + interceptor + render 执行流程
     */

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        /**
         * <pre>
         * 		 1.关于get出现乱码的问题处理的办法是约定:get提交的方式只是数字和字母
         * 		 2.1.jsp页面必须这样设置：<%@ pages language="java" import="java.util.*" pageEncoding="utf-8"%>
         * 		 2.2request.setCharacterEncoding("utf-8");
         * 		 2.3response.setCharacterEncoding("utf-8");
         * </pre>
         */
        // 编码设置
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 编码设置
        request.setCharacterEncoding(Constants.characterEncoding);
        response.setCharacterEncoding(Constants.characterEncoding);
        // 不能使用这句话-否则造成session丢失response.setHeader("SET-COOKIE", "JSESSIONID=" +
        // request.getSession().getId() + ";HttpOnly");

        // 相对于系统根目录的访问的路径
        String key = request.getServletPath();
        if (Index_Url.equals(key)) {// /
            key = Index_Url_To_Action_Url;
        }
        // 访问参数
        // String queryString = request.getQueryString();
        if (MvcConstants.isUseActionExtension) {
            int index = key.lastIndexOf(MvcConstants.actionExtension);
            if (index != -1) {
                key = key.substring(0, index);
            }
        }
        Action action = ActionMapping.getAction(key);
        if (action == null) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        } else {
            // 缓存控制器
            Controller controller = action.getController();

            ActionContext.setActionContext(request, response);
            if (Constants.devMode) {
                ActionReporter.doReport(controller, action);
            }
            (new ActionExecutor(action, controller)).invoke();
            Render render = ActionContext.getRender();
            // 下面这些渲染器是通过测试的
            // 核心处理：Action的渲染
            if (render instanceof ActionRender) {
                String actionUrl = ((ActionRender) render).getActionUrl();
                if (actionUrl == null || "".equals(actionUrl)) {
                    throw new IllegalArgumentException("将要跳转的Action的actionUrl为空");
                }
            }

            render.render();

        }

    }

}
